自动配置

初始化后的项目
Application.java不仅是启动引导类,还是配置类。
@SpringBootApplication开启组件扫描和自动配置。将三个有用的注解组合在了一起。
1.Spring的@Configuration:标明该类使用Spring基于Java的配置。
2.Spring的@ComponentScan:启用组件扫描,这样所写的Web控制器类和其他组件才能被自动发现并注册为Spring应用程序上下文中里的Bean。
3.Spring Boot的@EnableAutoConfiguration:这一行配置开启了Spring Boot自动配置的魔力,可以不再写成篇的配置了。

application.properties可以很方便地细粒度调整Spring Boot的自动配置。完全不用告诉Spring Boot加载application.properties,只要存在就会被加载。

Spring Boot项目构建插件
Spring Boot的构建插件对构建过程有所帮助,如Maven钟spring-boot-maven-plugin。构建插件的主要功能是把项目打包成一个可执行的超级JAR,包括把应用程序的所有依赖打入JAR文件中,并为JAR添加一个描述文件,其中的内容能用java -jar来运行应用程序。

指定基于功能的依赖
并不需要指定版本号,起步依赖本身的版本是由正在使用的Spring Boot的版本来决定的,而起步依赖则会决定它们引入的传递依赖版本。
Maven和gradle中使用构建工具来显示包含项目汇总每一个库以及它们的版本。

![]
(/img/media/Spring%20Boot%E5%AE%9E%E6%88%98%20%E5%85%A5%E9%97%A8/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202019-05-23%20%E4%B8%8A%E5%8D%888.13.40.png)

覆盖起步依赖引入的传递依赖
gradle

Maven


需要指定版本的依赖,则可以在pom.xml中覆盖传递依赖引入的另一个依赖。

gradle则是倾向于使用更新的依赖,若要指定老版本的生效,则要先将较新版本的exclude。

使用自动配置
Spring Boot的自动配置是一个运行时的过程,考虑了众多的因素,才决定Spring配置应该用哪一个不该用哪一个。例如。

专注于应用程序功能:1.定义领域模型如一个实体。2.定义仓库接口。3.创建Web界面。

1.@Entity注解表明对象是一个JPA实体。

id属性加了@Id@GeneratedValue注解,说明这个字段是实体的唯一标识,并且这个字段的值是自动生成的。

2.通过扩展JpaRepository,ReadingListRespository直接继承了18个执行常用持久化操作的方法。JpaRepository是个泛型接口,有两个参数:仓库操作的领域对象类型,及ID属性的类型。以及自己增加的方法findByReader()。只需定义仓库接口,在应用程序启动后,该接口在运行时会自动实现。

3.使用SpringMVC为应用程序处理HTTP请求。


@Controller注解,组件扫描会自动将其注册为Spring应用程序上下文的一个Bean。
@RequestMapping注解,将其中所有的处理器方法都映射到了”/”这个URL路径上。

在向应用程序加入 Spring boot时,有个名为spring-boot-autoconfigurel.JAR文件,其中包含了很多配置类。每个配置类都在应用程序的Classpath里,都有机会为应用程序的配置添砖加瓦。这些配置类里有用于 Thymeleaf的配置,有用于 Spring data JPa的配置,有用于 Spiring mvc的配置
还有很多其他东西的配置,你可以自己选择是否在 Spring应用程序里使用它们。其中利用了Spring的条件化配置,条件化配置运行配置存在于应用程序中,但在满足某些特定条件之前都忽略这个配置。在Spring里可以很方便地编写自己的条件,要做的就是实现Condition接口,覆盖它的matches方法。

下面的简单条件类只有在Classpath里存在JdbcTemplate时才会生效。

当用Java来声明Bean时,可以用自定义条件类。


在这个例子中,只有当JdbcTemplateCondition类的条件成立时才会创建MyService这个Bean。也就是说,MyService Bean创建条件是Classpath里有JdbcTemplate。否则,这个Bean的声明就会被忽略。

Classpath

自动配置会做出以下配置决策,它们和之前的例子息息相关。
1.因为Classpath里有H2,所以会创建一个嵌入式H2数据库Bean,它的类型是javax.sql.DataSource,JPA实现( Hibernate )需要它来访问数据库。
2.因为Classpath里有Hibernate ( Spring Data JPA传递引入的)的实体管理器,所以自动配置会配置与Hibernate相关的Bean,包括Spring的LocalContainerEntityManagerFactory Bean和JpaVendorAdapter。
3.因为Classpath里有Spring Data JIPA,所以它会自动配置为根据仓库的接口创建仓库实现。
4.因为Classpath里有Thymeleaf,所以Thymeleaf会配置为Spring MVC的视图,包括一个Thymeleaf的模板解析器、模板引擎及视图解析器。视图解析器会解析相对于Classpath根目录的 / templates目录里的模板。
5.因为Classpath里有SpringMVC(归功于Web起步依赖),所以会配置Spring的DispatcherServlet并启用Spring MVC。
6.因为这是一个Spring MVC Web应用程序,所以会注册一个资源处理器,把相对于Classpath根目录的 / static目录里的静态内容提供出来。(这个资源处理器还能处理 / public、/ resources和_META-INF_resources的静态内容。)
7.因为Classpath里有Tomcat(通过Web起步依赖传递引用),所以会启动一个嵌入式的Tomcat容器,监听8080端口。

自定义配置

覆盖Spring Boot自动配置
正如上面所讲。

@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

通过属性文件外置配置。
另一种方式是通过applocation.properties,yml也可以。

Spring Boot能从多种属性源获得属性,优先级从高到低是:
(1)命令行参数
(2) java: comp / env里的JNDI属性
(3)JVM系统属性
(4)操作系统环境变量
(5)随机生成的带random. * 前缀的属性
(6)应用程序以外的application. properties或者appliaction.yml文件
(7)打包在应用程序内的application.properties或者appliaction.yml文件
(8)通过@PropertySource标注的属性源
(9)默认属性

application. properties和application.yml文件能放在以下四个位置。优先级有高到低
(1)外置,在相对于应用程序运行目录的 / config子目录里。
(2)外置,在应用程序运行的目录里。
(3)内置,在config包内 。
(4)内置,在Classpath根目录。

同一优先级位置上,application.yml会覆盖application.properties的属性。

在application.yml / prop通常你都无需指定JDBC驱动,Spring Boot会根据数据库URL识别出需要的驱动,但如果识别出问题了,你还可以设置spring datasource.driver-class-name属性。在自动配置DataSourceBean的时候,SpringBoot会使用这里的连接数据。

DataSourceBean是一个连接池,如果Classpath里有Tomcat的连接池DataSource,那么就会使用这个连接池;否则,Spring Boot会在Classpath里查找以下连接池:HikariCP,Commons DBCP 2。还可以自己配置DataSource Bean,使用自己喜欢的各种连接池。

应用程序Bean的配置外置


@ConfigurationProperties注解说明该Bean的属性应该是(通过setter)从配置属性值注入的,更具体就是说明应该注入带amazon前缀的属性。

本例中ReadingListController只有一个setter方法,就是设置associateId属性用的setter方法。因此,设置Amazon Associate ID唯一要做的就是添加amazon.associateId属性,把它加入支持的任一属性源位置里即可。
例如在application.properties中设置:

开启配置属性从技 术上来说,@ConfigurationProperties注解不会生效,除非先向Spring配置类添加@EnableConfigurationProperties注解。但通常无需这么做,因为Spring Boot自动配置后面的全部配置类都已经加上了@EnableConfigurationProperties注解。因此,除非你完全不使用自动配置,否则就无需显式地添加@EnableConfigurationProperties

需要注意,Spring Boot的属性解析器非常智能,它会自动把驼峰规则的属性和使用连字符或下划线的同名属性关联起来。换句话说,amazon. associateId这个属性和amazon. associate_ id以及amazon.associate-id都是等价的。

在一个类里收集属性,创建一个单独的Bean,为它加上@ConfigurationProperties注解,让这个Bean收集所有配置属性。


有了加载amazon.associateld配置属性的AmazonProperties后,我们可以调整ReadingListController ,让它从注入的AmazonProperties中获取Amazon Associate ID。

使用Profile进行配置
Profile是一种条件化配置,基于运行时激活Profile,会使用或者忽略不同的Bean或配置类。


@Profile注解要求运行时激活production Profile,这样才能应用该配置。如果production Profile没有激活,就会忽略该配置。设置spring.profiles.active属性就能激活Profile,任意设置配置属性的方式都能用于设置这个值。

如果正在使用application.properties,可以创建额外的属性文件,遵循application-{profile}.properties命名格式,就能提供特定于Profile的属性了。
比如说生产环境,就是application-production.properties。

使用YAML就可以把所有的Profile的配置属性都放在一个application.yml文件里,例如: